package com.ruge.tools.antisamy.starter.filter;

import com.ruge.tools.antisamy.starter.wrapper.XssRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * description XSS过滤器
 * create Time at 2022/8/26 10:51
 *
 * @author alice.ruge
 * @since 0.0.7
 */
@Slf4j
public class XssFilter implements Filter {
    /**
     * 可放行的请求路径
     */
    private static final String IGNORE_PATH = "ignorePath";
    /**
     * 可放行的请求路径列表
     */
    private List<String> ignorePathList;

    @Override
    public void init(FilterConfig filterConfig) {
        log.debug("XSS filter [XSSFilter] init start ...");
        String ignorePaths = filterConfig.getInitParameter(IGNORE_PATH);
        if (!StringUtils.isBlank(ignorePaths)) {
            String[] ignorePathArr = ignorePaths.split(",");
            ignorePathList = Arrays.asList(ignorePathArr);
        }
        log.debug("ignorePathList=" + ignorePathList);
        log.debug("XSS filter [XSSFilter] init end");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        log.debug("XSS filter [XSSFilter] starting");
        // 判断uri是否包含项目名称
        String uriPath = ((HttpServletRequest) request).getRequestURI();
        if (isIgnorePath(uriPath)) {
            log.debug("ignore xss filter,path[" + uriPath + "] pass through XssFilter, go ahead...");
            chain.doFilter(request, response);
            return;
        } else {
            log.debug("has xss filter path[" + uriPath + "] need XssFilter, go to XssRequestWrapper");
            //传入重写后的Request
            chain.doFilter(new XssRequestWrapper((HttpServletRequest) request, null), response);
        }
        log.debug("XSS filter [XSSFilter] stop");
    }


    @Override
    public void destroy() {
        log.debug("XSS filter [XSSFilter] destroy");
    }

    private boolean isIgnorePath(String servletPath) {
        if (StringUtils.isBlank(servletPath)) {
            return true;
        }
        if (null == ignorePathList) {
            return false;
        } else {
            for (String ignorePath : ignorePathList) {
                if (!StringUtils.isBlank(ignorePath) && servletPath.contains(ignorePath.trim())) {
                    return true;
                }
            }
        }
        return false;
    }
}